package defectsim.resources.deformation;

import javax.vecmath.Vector2d;

import repast.simphony.parameter.Parameters;

import defectsim.SimulationEnvironment;

public class CyclicStrain implements Deformation{

	private SimulationEnvironment environment = SimulationEnvironment.getInstance();

	private double imposedStrainAmplitude;
	private double imposedStrainRate;
	private double imposedStressRate;
	private double strainRate;
	private double totalStrain;
	private double meanVelocity;
	private int directionSign;
	private boolean up;
	private double stress;

	public CyclicStrain(){
		Parameters p = environment.getParameters();
		this.imposedStrainAmplitude = (Double)p.getValue("imposedstrainamplitude");
		this.imposedStrainRate = (Double)p.getValue("imposedstrainrate");
		this.imposedStressRate = (Double)p.getValue("imposedstressrate");

		stress = 0.0;
		directionSign = 1;
		up = true;
	}

	@Override
	public Vector2d updateExternalStress() {
//		totalStrain += environment.getStrain();
		meanVelocity = environment.getMeanVelocity();
		System.out.printf("Mean velocity: %f m/s\n", meanVelocity);
		double timeStep = environment.getTimeStep();
		double x = meanVelocity * timeStep;
		double L = 10 * 1e-3;
		double rho = 500 / (L * L);
		totalStrain += 0.255 * x * 1.0e-9 * rho; 
//		strainRate = environment.getStrainRate();
		strainRate = 0.255 * meanVelocity * 1.0e-9 * rho;
//		strainRate = environment.getMetrics().getMeanStrainRate();
		double deltaStress = 0;

		double tempStrain = totalStrain;
		if (up && (Math.abs(totalStrain) > imposedStrainAmplitude)) {
			directionSign = -directionSign;
//			totalStrain = 0;
		}

		if (Math.abs(tempStrain) > imposedStrainAmplitude || directionSign * tempStrain < 0)
			up = false;
		else
			up = true;
		if (directionSign > 0){
			deltaStress = 0;
			if(strainRate < imposedStrainRate)
				deltaStress = imposedStressRate * timeStep;
		}
		else {
			deltaStress = imposedStressRate * timeStep * directionSign;
			if (strainRate < imposedStrainRate * directionSign)
				deltaStress = 0;
		}
		stress += deltaStress;
		System.out.printf("ImposedStrain: %e, ImposedStrainRate: %f\n", imposedStrainAmplitude, imposedStrainRate);
		System.out.printf("TotalStrain: %e, StrainRate: %f, Stress: %f, Sign: %d, Up: %b\n", totalStrain, strainRate, stress, directionSign, up);
		return new Vector2d(stress, 0.0);
	}

	@Override
	public double getCycle() {
		// TODO Auto-generated method stub
		return 0;
	}
}
